package com.gitee.qdbp.general.common.biz.event.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.api.event.enums.Operate;
import com.gitee.qdbp.general.common.api.event.enums.Pointer;
import com.gitee.qdbp.general.common.api.event.model.IEventListener;
import com.gitee.qdbp.general.common.api.event.service.IEventCenter;

/**
 * 事件调度中心
 *
 * @author zhaohuihua
 * @version 170724
 */
// @Service
public class EventCenter implements IEventCenter {

    private Map<String, List<IEventListener<?, ?, ?>>> map;

    public EventCenter() {
        this.map = new ConcurrentHashMap<>();
    }

    @Override
    public List<IEventListener<?, ?, ?>> getListener(String dataType) {
        return map.get(dataType);
    }

    @Override
    public void addListener(String dataType, IEventListener<?, ?, ?> listener) {
        String key = dataType.intern();
        synchronized (key) {
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<IEventListener<?, ?, ?>>());
            }
            map.get(key).add(listener);
        }
    }

    @Override
    public boolean removeListener(String dataType) {
        return map.remove(dataType) != null;
    }

    @Override
    public boolean removeListener(String dataType, IEventListener<?, ?, ?> listener) {
        if (map.containsKey(dataType)) {
            return map.get(dataType).remove(listener);
        } else {
            return false;
        }
    }

    @Override
    public void clear() {
        map.clear();
    }

    @Override
    public void trigger(String dataType, Operate operate, Pointer pointer, Object object) throws ServiceException {
        List<IEventListener<?, ?, ?>> listeners = map.get(dataType);

        if (listeners != null) {
            for (IEventListener<?, ?, ?> i : listeners) {
                trigger(i, operate, pointer, object);
            }
        }
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void trigger(IEventListener listener, Operate operate, Pointer pointer, Object object)
            throws ServiceException {

        if (listener == null || operate == null || pointer == null || object == null) {
            return;
        }

        switch (pointer) {
        case BEFORE:
            switch (operate) {
            case CREATE:
                listener.beforeCreate(object);
                break;
            case UPDATE:
                listener.beforeUpdate(object);
                break;
            case DELETE:
                listener.beforeDelete(object);
                break;
            }
            break;
        case AFTER:
            switch (operate) {
            case CREATE:
                listener.afterCreate(object);
                break;
            case UPDATE:
                listener.afterUpdate(object);
                break;
            case DELETE:
                listener.afterDelete(object);
                break;
            }
            break;
        }
    }
}
